Source Resolver
In Imperat, SourceResolver<S extends Source, R> is an interface designed to handle the resolution of platform-specific command sources (S) into custom types (R). This allows for the flexibility of customizing the command source based on the platform, enabling developers to transform platform-specific command senders into their own command source representations.
Source Interface
Source is an interface representing the command sender on a given platform. Since Imperat is designed to work across multiple platforms, the type of S depends on the platform you're working with. For example, in a Bukkit environment, BukkitSource would implement the Source interface, representing the sender of a command in Bukkit.
The purpose of the SourceResolver is to map a command sender (such as BukkitSource) into a custom type (R) that better fits the needs of your project.
Interface Definition
The SourceResolver interface is simple in its design:
public interface SourceResolver<S extends Source, R> {
R resolve(S source) throws ImperatException;
}
S: The platform-specific source, e.g.,BukkitSourcein Bukkit.R: The resolved type, representing your custom command source.resolve(S source): This method transforms a platform-specific source into a custom typeR. It can throw anImperatExceptionto signal any issues during the resolution process.
Example of Custom Source
Here's an example of a custom class representing a player on a given platform:
public final class CustomPlayer {
private final CommandSender sender;
public CustomPlayer(CommandSender sender) {
this.sender = sender;
}
public void sendMessage(String msg) {
sender.sendMessage(msg);
}
public void greet() {
sendMessage("Greetings " + sender.getName());
}
// Additional methods to access player-specific data
}
Example: Implementing a SourceResolver
Below is an example of how to create a SourceResolver for Bukkit's BukkitSource, which transforms it into a custom CustomPlayer type:
public class CustomSourceResolver implements SourceResolver<BukkitSource, CustomPlayer> {
@Override
public @NotNull CustomPlayer resolve(BukkitSource source) throws ImperatException {
if (source.isConsole()) {
throw new SourceException("Only players are allowed to execute this command");
}
return new CustomPlayer(source.origin());
}
}
In this example:
- The
resolvemethod checks if the source is a console (and disallows it) and otherwise returns aCustomPlayerinstance, wrapping the originalCommandSender.
Registering a SourceResolver
Once your SourceResolver is implemented, you can register it with Imperat as follows:
imperat = BukkitImperat.builder(plugin)
.sourceResolver(CustomPlayer.class, new CustomSourceResolver())
.build();
This allows Imperat to resolve BukkitSource into your CustomPlayer type whenever necessary.
Example Usage
This can be used differently depending on the way your making your commands (whether Classic or Annotations)
Classic example
imperat.registerCommand(
Command.<BukkitSource>create("test")
.usage(
CommandUsage.<BukkitSource>builder()
.parameters(CommandParameter.requiredText("txt"))
.execute((source, ctx)-> {
CustomPlayer customPlayer = ctx.getResolvedSource(CustomPlayer.class);
String txt = ctx.getArgument("txt");
//do whatever you want with custom player
customPlayer.greet();
customPlayer.sendMessage("The text you entered is '" + txt + "'");
})
).build()
);
Annotations example
public final class TestCommand {
@Usage
public void someUsage(CustomPlayer player, @Named("txt") String txt) {
player.greet();
player.sendMessage("The text you entered is '" + txt + "'");
}
}